package util

import (
	"fmt"
	"io"
	"os"
	"path/filepath"
)

type FuncFile func(string, os.FileInfo) error

func WalkFile(root string, funcFile FuncFile) error {
	err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
		err = funcFile(path, info)
		if err != nil {
			fmt.Printf("999%+v", err)
			return err
		}
		return nil
	})

	return err
}

// IsBinaryFile 判断文件是否为二进制文件
// fname: 要判断的文件名（包含路径）
// 返回值: 如果是二进制文件返回true，否则返回false
func IsBinaryFile(fname string) bool {
	f, err := os.Open(fname)
	if err != nil {
		return false
	}
	defer func(f *os.File) {
		err := f.Close()
		if err != nil {
			fmt.Printf("%+v", err)
		}
	}(f)

	var maxR int64 = 32 // 最多读取32个字节

	// 获取文件大小
	if fi, err := f.Stat(); err == nil {
		if fi.Size() == 0 {
			return false // 空文件认为是文本文件
		}
		if fi.Size() < maxR {
			maxR = fi.Size()
		}
	}

	// 读取指定大小的数据
	reader := io.LimitReader(f, maxR)
	fbs := make([]byte, maxR)
	if _, err := reader.Read(fbs); err != nil {
		return false
	}

	// 判断是否包含非打印字符
	for _, v := range fbs {
		if v == 0 || v > 127 {
			return true // 包含控制字符或非ASCII字符，认为是二进制文件
		}
	}

	return false // 未发现控制字符，认为是文本文件
}
